package bg.btanev.eightyfour.service.impl;

import java.util.List;

import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import bg.btanev.eightyfour.dao.exception.DependentObjectExpection;
import bg.btanev.eightyfour.domain.Tag;
import bg.btanev.eightyfour.domain.Target;
import bg.btanev.eightyfour.domain.person.Person;
import bg.btanev.eightyfour.domain.target.TargetStatus;
import bg.btanev.eightyfour.repository.TagRepository;
import bg.btanev.eightyfour.repository.TargetRepository;
import bg.btanev.eightyfour.service.TargetService;
import bg.btanev.eightyfour.shared.state.TargetState;

/**
 *
 * @author B.Tanev
 *
 */
public class TargetServiceImpl implements TargetService {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(TargetServiceImpl.class);

	private TargetRepository targetRepository;
	private TagRepository tagRepository;

	public TargetServiceImpl() {
	}

	public void setTargetRepository(TargetRepository targetRepository) {
		this.targetRepository = targetRepository;
	}

	public void setTagRepository(TagRepository tagRepository) {
		this.tagRepository = tagRepository;
	}

	@Override
	public void updateTarget(Long identifier) {
		logger.debug("updateTarget(Long) - start"); //$NON-NLS-1$
		Validate.notNull(identifier);

		Target target = targetRepository.findByIdentifier(identifier);
		if (target != null) {
			updateTarget(target);
			targetRepository.flushLocalCache();
			targetRepository.clearLocalCache();
		} else {
			logger.debug("updateTarget(Long) - Target with id '{}' does not exists.", identifier); //$NON-NLS-1$
		}

		logger.debug("updateTarget(Long) - end"); //$NON-NLS-1$
	}

	@Override
	public void updateTarget(Target target) {
		logger.debug("updateTarget(Target) - start"); //$NON-NLS-1$

		Validate.notNull(target);

		TargetStatus status = target.getStatus();
		if (status.getState() == TargetState.ACTIVE) {
			if (status.getUpdateState() == TargetState.TOPROCESS) {
				Tag.clearLocalTagsCache();
				target.updateProfiles();
				Tag.clearLocalTagsCache();

				try {
					targetRepository.storeTarget(target);
				} catch (DependentObjectExpection e) {
					logger.error("updateTarget(Target) - constrainer violation exception!", e); //$NON-NLS-1$
				}
				targetRepository.flushLocalCache();
				targetRepository.removeFromLocalCache(target);
			} else {
				logger.debug("updateTarget(Target) - Target is not in 'TOPROCESS' update state"); //$NON-NLS-1$
			}
		} else {
			logger.debug("updateTarget(Target) - Target is not in 'ACTIVE' state"); //$NON-NLS-1$
		}

		logger.debug("updateTarget(Target) - end"); //$NON-NLS-1$
	}

	@Override
	public Target createAndStoreTarget(Person person) {
		return targetRepository.createAndStoreTarget(person);
	}

	@Override
	public void deleteTarget(Target target) {
		targetRepository.removeTarget(target);
	}

	@Override
	public Target findByPerson(Person person) {
		return targetRepository.findByPerson(person);
	}

	@Override
	public Target findByIdentifier(Long id) {
		return targetRepository.findByIdentifier(id);
	}

	@Override
	public void saveTarget(Target target) {
		targetRepository.storeTarget(target);
	}

	@Override
	public List<Target> findBySearchDetails(String firstName, String lastName, String email) {
		logger.debug("findBySearchDetails(String, String, String) - start"); //$NON-NLS-1$

		List<Target> result = targetRepository.findTargets(email, firstName, lastName);



		logger.debug("findBySearchDetails(String, String, String) - end"); //$NON-NLS-1$
		return result;
	}

	@Override
	public List<Tag> findTagsForTarget(Target target) {
		return tagRepository.findTagsForTarget(target);
	}
}
